﻿using log4net;
using server.DAO;
using server.Model;
using server.Tool;
using ServerFramework.Tool.Singleton;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;


namespace server
{
    /// <summary>
    /// 处理地图推送相关的业务逻辑
    /// </summary>
    public  class MapDataPushHandle: Singleton<MapDataPushHandle>
    {
        private ILog Logger = log4net.LogManager.GetLogger("server.MapDataPushHandle");
        private JoinRoomDao joinRoomDao;
        private SearchGrounpDao searchGrounpDao;
        private UserDao registerDao = new UserDao();
        private UserRoomDao userRoomDao = new UserRoomDao();
        private RoomDao roomDao = new RoomDao();
        private CURDRoomDao curdRoomDao = new CURDRoomDao();

        public void Init()
        {
            //获取
            searchGrounpDao = new SearchGrounpDao();
            joinRoomDao = new JoinRoomDao();
        }

   
        /// <summary>
        /// 实时推送地图数据
        /// </summary>
        public   void RealPushMapData()
        {

            CresteRoomUserIdData();
            ConcurrentDictionary<PubgSession, SessionItem> dic = PubgSession.mOnLineConnections;
            foreach (PubgSession session in dic.Keys)
            {
                SessionItem sessionItem = null;
                dic.TryGetValue(session, out sessionItem);
                if (sessionItem != null && !string.IsNullOrEmpty(sessionItem.gpsItem.userName) && sessionItem.isLogin)
                {
                    //获取所有的队员或者管理员下的所有队员的列表
                    List<GPSUserItem> gpsList = GetGpsUserListByUser(sessionItem.gpsItem);
                    Grounp grounp = null;
                    int roomId=0;
                    //0为队长或者队员
                    if (sessionItem.gpsItem.userType==0)
                    {
                         roomId = GetRoomByUser(sessionItem.gpsItem.userId);
                        //没有加入到房间
                        if(roomId==-1)
                        {
                            continue;
                        }
                         grounp = curdRoomDao.GetGrounpByRoomId(roomId);
                    }
                    //1为管理员
                    else
                    {
                        grounp = searchGrounpDao.GetGrounpByAdmin(sessionItem.gpsItem.userId);
                    }
                    //没有加入游戏战队
                    if(grounp==null)
                    {
                        continue;
                    }
                   
                    Dictionary<string, object> dataDic = new Dictionary<string, object>();
                    //玩家和队长
                    if (sessionItem.gpsItem.userType == 0)
                    {
                        Room room = GetRoomById(roomId);
                        dataDic.Add("room", room);
                        Life life = registerDao.GetLifeById(sessionItem.gpsItem.userId);
                        dataDic.Add("life", life);
                    }
                    else
                    {
                        dataDic.Add("room", null);
                        dataDic.Add("life", null);
                    }
                    dataDic.Add("grounp", grounp);
                    dataDic.Add("gpsData", gpsList);
                  
                    string resultJson = Utils.CollectionsConvert.ToJSON(dataDic);
                    // Logger.InfoFormat("userName={0},gpsData={1}", sessionItem.gpsItem.userName, resultJson);
                    string data = "ShowPosition" + Constant.START_SPLIT + resultJson + "\r\n";
                    if (grounp.runState ==-1)
                    {
                        continue;
                    }
                    session.Send(data);
                }
            }

        }


        /// <summary>
        /// 形成roomid，List<userid>
        /// </summary>
        /// <param name="room_User_list"></param>
        private void CresteRoomUserIdData()
        {
            List<Room_User> room_User_list = joinRoomDao.SearchAllRoomUser();
            //去除重复的
            var roomlist = room_User_list.GroupBy(p => p.room_id).Select(g => g.First()).ToList();
            Dictionary<string, List<int>> roomUserIDDic = new Dictionary<string, List<int>>();
            roomlist.ForEach((item) => {

                int roomId = item.room_id;
                var query = from s in room_User_list
                            where s.room_id == roomId
                            select s.user_id;
                roomUserIDDic.Add(roomId.ToString(), query.ToList<int>());

            });


            room_gpsDic.Clear();
            foreach (string roomId in roomUserIDDic.Keys)
            {
                List<int> userids = roomUserIDDic[roomId];
                List<GPSUserItem> gpsList = GetGPSListByUser(userids);
                if (gpsList.Count > 0)
                {
                    room_gpsDic.Add(roomId, gpsList);
                }
            }

        }
        private Dictionary<string, List<GPSUserItem>> room_gpsDic = new Dictionary<string, List<GPSUserItem>>();

        
        /// <summary>
        /// userid 换成gps list
        /// </summary>
        /// <param name="userids"></param>
        /// <returns></returns>

        private List<GPSUserItem> GetGPSListByUser(List<int> userids)
        {
            List<GPSUserItem> gpsList = new List<GPSUserItem>();
            userids.ForEach((userId) => {

                ConcurrentDictionary<PubgSession, SessionItem> dic = PubgSession.mOnLineConnections;
                foreach (SessionItem sessionItem in dic.Values)
                {
                    if (sessionItem.gpsItem != null && !string.IsNullOrEmpty(sessionItem.gpsItem.userName) && sessionItem.gpsItem.userId == userId)
                    {
                        gpsList.Add(sessionItem.gpsItem);
                    }
                }

            });
            return gpsList;
        }

        /// <summary>
        /// 通过userid查询所在的room
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>
        public int GetRoomByUser(int userId)
        {
            return userRoomDao.GetRoomIdByUser(userId);
        }
        /// <summary>
        /// 如果是队员或者队长，获取该组的成员列表，如果是管理员，获取的是该游戏下的所有成员
        /// </summary>
        /// <param name="userGpsItem"></param>
        /// <returns></returns>
        public List<GPSUserItem> GetGpsUserListByUser(GPSUserItem userGpsItem)
        {
            //玩家
            if (userGpsItem.userType == 0)
            {
                int roomId = GetRoomByUser(userGpsItem.userId);
                if (room_gpsDic.ContainsKey(roomId.ToString()))
                {
                    return room_gpsDic[roomId.ToString()];
                }
                return null;
            }
            //管理员
            else if (userGpsItem.userType == 1)
            {
                //查询所有用户的grounp
                List<int> grounpIDs = searchGrounpDao.SearchGrounpListByUser(userGpsItem.userId);
                List<GPSUserItem> result = new List<GPSUserItem>();
                if (grounpIDs.Count > 0)
                {
                    int grounpID = grounpIDs[0];
                    int[] roomIds = GetRoomListByGrounpId(grounpID);
                    for (int k = 0; k < roomIds.Length; k++)
                    {
                        if (room_gpsDic.ContainsKey(roomIds[k].ToString()))
                        {
                            int _roomID = roomIds[k];
                            List<GPSUserItem> gpsList = room_gpsDic[_roomID.ToString()];
                            if (gpsList != null)
                            {
                                SetGpsUserRoomIndex(grounpID, _roomID, gpsList);
                                result.AddRange(gpsList);
                            }
                        }
                    }
                }
                return result;
            }

            return null;
        }
        /// <summary>
        ///  获取 roomID ，在grounpID中的索引 ，用于前端展示不同队之间不同的颜色
        /// </summary>
        /// <param name="grounpID"></param>
        /// <param name="roomID"></param>
        /// <returns></returns>
        private void  SetGpsUserRoomIndex(int grounpID, int roomID, List<GPSUserItem> gpsList)
        {
            List<Room> roomList = roomDao.SearchRoomListByGrounpID(grounpID.ToString());
            int index = 0;
            for(int i=0;i< roomList.Count;i++)
            {
                if (roomList[i].id == roomID)
                {
                    index = i;
                    break;
                }
            }

            foreach(GPSUserItem item in gpsList)
            {
                item.roomIndex = index;
            }
        }
     
        public int[] GetRoomListByGrounpId(int grounpID)
        {
            List<Room> roomList = roomDao.SearchAllRoom();
            var result = roomList.Where(a => a.grounpId == grounpID);
            int[] roomIds = result.Select(a => a.id).ToArray();
            return roomIds;
        }

        public Room GetRoomById(int roomID)
        {
            List<Room> roomList = roomDao.SearchAllRoom();
            var room = roomList.Where(a => a.id == roomID).FirstOrDefault<Room>();
            return room;
        }

    }
}
